// 当事件触发时，相应的函数并不会立即触发，而是会等待一定的时间；
// 当事件密集触发时，函数的触发会被频繁的推迟；
// 只有等待了一段时间也没有事件触发，才会真正的执行响应函数；

// 总结而言：
// 在规定的时间第n秒后才会执行回调，如果在n秒内又被触发，则会进行重置（重新计时）
// 也就是
// 在规定的一定的时间后才会执行回调，如果在这段时间内又触发了事件，则会将状态进行重置并重新进行计时，
// 直到时间重新到达规定的时间后才会执行回调

function debounce(fn, delay, immediate = false, resultCallBack) {
  let timer = null;
  let isInvoke = false;

  const _debounce = function (...args) {
    return new Promise((resolve, reject) => {
      if (timer) clearTimeout(timer);

      if (immediate && !isInvoke) {
        const result = fn.apply(this, args);
        if (resultCallback) resultCallBack(result);
        resolve(result);
        isInvoke = true;
      } else {
        timer = setTimeout(() => {
          const result = fn.apply(this, args);
          if (resultCallback) resultCallBack(result);
          resolve(result);
          timer = null;
          isInvoke = false;
        }, delay);
      }
    });
  };

  _debounce.cancel = function () {
    if (timer) clearTimeout(timer);
    timer = null;
    isInvoke = false;
  };
  return _debounce;
}
